package com.cscj.android.repository.settings.impl

import android.content.Context
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import com.cscj.android.repository.repo.config.WebViewConfig
import com.cscj.android.repository.settings.Settings
import com.cscj.android.repository.settings.model.SettingConstants
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.map
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject


class BrowserSettingImpl(
    context: Context
) : Settings.BrowserSetting, KoinComponent {

    companion object {
        private val Context.darkModeDataStore by preferencesDataStore("com.cssq.dataStore.browserSetting")

        private val keyDarkMode = intPreferencesKey("darkMode")
        private val keyFontSize = intPreferencesKey("fontSize")
        private val keyImageMode = intPreferencesKey("imageMode")
        private val keyReaderMode = booleanPreferencesKey("readerMode")
        private val keyPrivacyMode = booleanPreferencesKey("privacyMode")
        private val keyLockPortrait = booleanPreferencesKey("lockPortrait")
        private val keyBlockIntent = booleanPreferencesKey("blockIntent")

    }

    private val dataStore by lazy {
        context.darkModeDataStore
    }

    private val userAgentSetting by inject<Settings.UserAgentSetting>()

    override suspend fun updateDarkMode(darkMode: Int) {
        dataStore.edit {
            it[keyDarkMode] = darkMode
        }
    }

    override fun darkModeFlow(): Flow<Int> {
        return dataStore.data.map {
            it[keyDarkMode] ?: SettingConstants.DefaultDarkMode
        }
    }

    override fun fontSizeFlow(): Flow<Int> {
        return dataStore.data.map {
            it[keyFontSize] ?: SettingConstants.DefaultFontSize
        }
    }

    override suspend fun updateFontSize(fontSize: Int) {
        if (fontSize < 80 || fontSize > 160) return
        dataStore.edit {
            it[keyFontSize] = fontSize
        }
    }

    override fun readerModeFlow(): Flow<Boolean> {
        return dataStore.data.map {
            it[keyReaderMode] ?: false
        }
    }

    override suspend fun updateReaderMode(on: Boolean) {
        dataStore.edit {
            it[keyReaderMode] = on
        }
    }

    override suspend fun updateImageMode(imageMode: Int) {
        dataStore.edit {
            it[keyImageMode] = imageMode
        }
    }

    override fun imageModeFlow(): Flow<Int> {
        return dataStore.data.map {
            it[keyImageMode] ?: SettingConstants.DefaultImageMode
        }
    }

    override fun webViewConfigFlow(): Flow<WebViewConfig> {
        return dataStore.data.map {
            val userAgent = userAgentSetting.currentUserAgent().firstOrNull()?.content
            WebViewConfig(
                darkMode = it[keyDarkMode] ?: SettingConstants.DefaultDarkMode,
                readerMode = it[keyReaderMode] ?: false,
                fontSize = it[keyFontSize] ?: SettingConstants.DefaultFontSize,
                userAgent = userAgent ?: SettingConstants.AndroidUserAgent,
                imageMode = it[keyImageMode] ?: SettingConstants.DefaultImageMode,
                enableHistory = !(it[keyPrivacyMode] ?: false),
                blockIntent = it[keyBlockIntent] ?: false
            )
        }
    }

    override fun privacyModeFlow(): Flow<Boolean> {
        return dataStore.data.map {
            it[keyPrivacyMode] ?: false
        }
    }

    override suspend fun updatePrivacyMode(on: Boolean) {
        dataStore.edit {
            it[keyPrivacyMode] = on
        }
    }

    override fun lockPortraitFlow(): Flow<Boolean> {
        return dataStore.data.map {
            it[keyLockPortrait] ?: false
        }
    }

    override fun blockIntentFlow(): Flow<Boolean> {
        return dataStore.data.map {
            it[keyBlockIntent] ?: false
        }
    }

    override suspend fun updateBlockIntent(block: Boolean) {
        dataStore.edit {
            it[keyBlockIntent] = block
        }
    }

    override suspend fun updateLockScreen(lockPortrait: Boolean) {
        dataStore.edit {
            it[keyLockPortrait] = lockPortrait
        }
    }

    override suspend fun clearAll() {
        dataStore.edit {
            it.clear()
        }
    }
}